package com.mqb.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mqb.*;
import com.mqb.db.SqliteHelper;
import com.mqb.session.MsgSession;
import com.mqb.util.ByteBufUtil;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;

/**
 * 接受服务端消息的处理器
 */
@ChannelHandler.Sharable
public class ClientMessageReceiveHandler extends ChannelInboundHandlerAdapter {
    private static final Logger log = LoggerFactory.getLogger(ClientMessageReceiveHandler.class);

    private SqliteHelper sqliteHelper = new SqliteHelper(System.getProperty("user.dir")+ File.separator+"im-client" + File.separator + "db" + File.separator+"client.db");

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("received message: {}", msg.toString());

        JSONObject jsonObject = JSON.parseObject(msg.toString());

        String msgTypeCode = jsonObject.getString(MsgConstant.MSG_TYPE);
        if (MsgType.isAck(msgTypeCode)) {
            AckMsg ackMsg = JSON.parseObject(msg.toString(), AckMsg.class);
            log.info("ACK 收到服务器响应：server >> "+jsonObject.getString(MsgConstant.CONTENT));
            MsgSession.plus(ackMsg.getId());

        }else if(MsgType.isDeliver(msgTypeCode)) {
            // 表示当前作为消息接受方

            DeliverMsg deliverMsg = JSON.parseObject(msg.toString(), DeliverMsg.class);
            RequestMsg oriRequestMsg = JSON.parseObject(deliverMsg.getDeliverContent(), RequestMsg.class);

            // 重复消息处理(先回复，再去重)

            // 无论是否重复数据，都回应服务端我已收到，取出部分msg属性，减小传输大小
            // Thread.sleep(10000); 模拟消息超时
            ctx.writeAndFlush(ByteBufUtil.transferWithHead(oriRequestMsg.swap().setReceivedFlag(true).setContent(null)));

            List<String> msgIds = sqliteHelper.executeQuery("select * from msg_received where user_id='mario'", (rs, index) -> rs.getString("msg_id"));

            if(!msgIds.contains(oriRequestMsg.getId())){ // 不是重复
                log.info("DELIVER 收到服务器传递：{} >> ", deliverMsg.getDeliverContent());

                String dml = String.format("insert into msg_received(user_id, msg_id) values('%s', '%s')", oriRequestMsg.getRecId(), oriRequestMsg.getId());
                sqliteHelper.executeUpdate(dml);
            }else{ // 重复
                log.info("DELIVER 收到重复数据：{} >> ", deliverMsg.getDeliverContent());
            }


        }
        else if(MsgType.isNotify(msgTypeCode)){
            NotifyMsg notifyMsg = JSON.parseObject(msg.toString(), NotifyMsg.class);
            log.info("NOTIFY 收到服务器提醒，目标已收到消息：server >> "+jsonObject.getString(MsgConstant.CONTENT));
            MsgSession.plus(notifyMsg.getId());

        }
        else {
            throw new IllegalStateException("未知类型");
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("出现异常", cause);
        super.exceptionCaught(ctx, cause);
    }
}
